package com.zhb.smartlocks;

import android.util.Base64;
import android.util.Log;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Created by zhbaust on 2020年4月1日.
 * 安卓端AES加密
 */
public class AesUtils {
    private static final String TAG="MainActivity";

    //加密用的Key 可以用26个字母和数字组成 此处使用AES-128-ECB加密模式，key需要为16位。
    private String sKey="1234567812345678";
    //向量
    private static String ivParameter = "";
    private static AesUtils instance = null;

    private AesUtils(String sKey) {
        this.sKey = sKey;
    }

    public static AesUtils getInstance(String sKey) {
        if (instance == null)
            instance = new AesUtils(sKey);
        return instance;
    }

    /**
     * 加密后返回Base64编码
     * @param sSrc
     * @return
     * @throws Exception
     */
    public String encryptToBase64(String sSrc) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
        byte[] raw = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        //IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
        return Base64.encodeToString(encrypted, Base64.DEFAULT);// 此处使用BASE64做转码。
    }

    /**
     * // 加密,返回Hex
     * @param encData 明文
     * @return
     * @throws Exception
     */
    public String encryptToHex(String encData) throws Exception {
        byte[] encrypted=encrypt(encData,sKey);
        return ByteUtils.byteArrayToHexString(encrypted);  // 此处使用BASE64做转码。（处于android.util包）
    }

    /**
     * 加密后返回字节数组
     * @param encData 明文
     * @return
     * @throws Exception
     */
    public  byte[] encrypt(String encData) throws Exception {
        return encrypt(encData,sKey);

    }

    /**
     * 加密后返回字节数组
     * @param encData 明文
     * @param secretKey 密钥
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(String encData, String secretKey) throws Exception {

        if (secretKey == null) {
            return null;
        }
        if (secretKey.length() != 16) {
            return null;
        }
        Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
        byte[] raw = secretKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        //IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8"));
        return encrypted;

    }

    /**
     * // 加密,返回Base64
     * @param encData 明文
     * @param secretKey 密钥
     * @return
     * @throws Exception
     */
    public static String encryptBase64(String encData, String secretKey) throws Exception {
        byte[] encrypted=encrypt(encData,secretKey);
        return Base64.encodeToString(encrypted, Base64.DEFAULT);// 此处使用BASE64做转码。（处于android.util包）
    }

    /**
     * // 加密,返回Hex
     * @param encData 明文
     * @param secretKey 密钥
     * @return
     * @throws Exception
     */
    public static String encryptToHex(String encData, String secretKey) throws Exception {
        byte[] encrypted=encrypt(encData,secretKey);
        return ByteUtils.byteArrayToHexString(encrypted);  // 此处使用BASE64做转码。（处于android.util包）
    }

    /**
     * 从Base64编码的密文解密
     * @param sSrc
     * @return
     */
    public String decrypt(String sSrc) {
        try {
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            //IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] encrypted1 = Base64.decode(sSrc, Base64.DEFAULT);// 先用base64解密
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }
    /**
     *从字节数组进行解密
     * @param sSrc
     * @return
     */
    public String decrypt(byte [] sSrc) {
        try {

            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);

            byte[] original = cipher.doFinal(sSrc);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 从Hex编码的密文解密
     * @param sSrc
     * @return
     */
    public String decryptHex(String sSrc) {
        try {
            byte [] src=ByteUtils.hexToByteArr(sSrc); //转换成字节数组
            return decrypt(src);
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * 从Hex编码的密文解密
     * @param sSrc Hex密文
     * @param key
     * @return
     */
    public static String decryptFromHex(String sSrc, String key) {
        try {
            byte [] src=ByteUtils.hexStr2Byte(sSrc); //转换成字节数组
            String originalString = decrypt(src,key);
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }
    // 解密

    /**
     * 从Base64编码的密文解密
     * @param sSrc Base64编码
     * @param key 字符串
     * @return 字符串
     */
    public static String decryptFromBase64(String sSrc, String key) {
        try {
            byte[] encrypted = Base64.decode(sSrc, Base64.DEFAULT);// 先用base64解密
            return decrypt(encrypted,key);
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     *从字节数组进行解密
     * @param sSrc
     * @param key
     * @return
     */
    public static String decrypt(byte [] sSrc, String key) {
        try {

            byte[] raw = key.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);

            byte[] original = cipher.doFinal(sSrc);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }
}
